extends Control

onready var input_bt_scene = preload("input_setting_button.tscn")
onready var action_list = $MarginContainer/VBoxContainer/ScrollContainer/ActionList

var vbase = null

var is_remap = false   # 是否处于重设状态
var action_to_remap = null   # 需要重设的动作
var remap_bt = null  # 需要重设的按钮

var tmp_actions = {} # 当前输入事件信息
var action_link_bt = {} # 存储Action与bt的对应信息

onready var reset_bt = $MarginContainer/VBoxContainer/HBoxContainer/ResetButton
onready var save_bt = $MarginContainer/VBoxContainer/HBoxContainer/SaveButton

func _ready():
	vbase = sys.get_node("VEBase")
	load_local_actions()
	load_built_in_actions()
	create_action_list()
	reset_bt.connect("pressed",self,"reset_all_actions")
	save_bt.connect("pressed",self,"save_input_setting")

# 创建键盘映射按钮
func create_action_list():
	for action in tmp_actions:
		var action_info = tmp_actions.get(action)
		if !check_action_able(action_info):continue
		if add_action(action,action_info) == null:continue
		
		var bt = input_bt_scene.instance()
		var action_label = bt.find_node("LabelAction")
		var input_label = bt.find_node("LabelAction2")
		
		if action_info.get("show_name"):
			action_label.text = action_info.get("show_name")
		else:
			action_label.text = action
		
		var events = InputMap.get_action_list(action)
		if events.size() > 0:
			input_label.text = trans_event_to_name(events[0])
		else:
			input_label.text = ""
		
		bt.connect("pressed",self,"_setting_button_pressed",[bt,action])
		action_list.add_child(bt)
		action_link_bt[action] = bt

# 重设键位
func _setting_button_pressed(bt,act):
	if !is_remap:
		is_remap = true
		action_to_remap = act
		remap_bt = bt
		remap_bt.find_node("LabelAction2").text = "请输入新的按键..."

# 记录新键位
func _input(event):
	if is_remap:
		if event is InputEventKey || (event is InputEventMouseButton && event.is_pressed()):
			if event.get("doubleclick") == true:
				event.doubleclick = false
			InputMap.action_erase_events(action_to_remap)
			InputMap.action_add_event(action_to_remap,event)
			_update_action_list(remap_bt,action_to_remap,event)
			clear_remap()
			accept_event()

# 更新按钮
func _update_action_list(bt,old_action,event):
	var event_name = trans_event_to_name(event)
	bt.find_node("LabelAction2").text = event_name
	
	if event is InputEventKey:
		tmp_actions[old_action]["latest_setting"] = [
			event_name,0,event.scancode,event.physical_scancode,
			event.shift,event.alt,event.control
		]
	elif event is InputEventMouseButton:
		tmp_actions[old_action]["latest_setting"] = [
			event_name,1,event.button_index,0,false,false,false
		]

# 重设初始化
func clear_remap():
	is_remap = false
	remap_bt = null
	action_to_remap = null
	
# 将事件转换为可读的名称
func trans_event_to_name(event):
	var event_name = ""
	if event is InputEventMouseButton:
		match event.button_index:
			1:event_name = "鼠标左键"
			2:event_name = "鼠标右键"
			3:event_name = "鼠标中键"
			_:event_name = event.as_text()
		# if event.doubleclick:
		#	event_name += "(双击)"
	else:
		event_name = event.as_text().replace("Kp ","小键盘").trim_suffix(" (Physical)")
	return event_name

# 加载mod内置事件信息
func load_built_in_actions():
	var bi_actions = data.getList("inputSetting")
	for bia in bi_actions:
		var ins = load(bia.dir).new()
		var actions = ins.get("actions")
		if actions == null:continue
		
		if !tmp_actions:
			tmp_actions = actions
		else:
			var keys = actions.keys()
			for k in keys:
				if tmp_actions.has(k):continue
				tmp_actions[k] = actions[k]

# 保存键位设置
func save_input_setting(is_save_now=true):
	vbase.setSetting("inputSetting","actions",tmp_actions,is_save_now)
	
# 加载键位设置
func load_local_actions():
	var local_actions = vbase.getSetting("inputSetting","actions")
	if local_actions == null:return
	if !tmp_actions:
		tmp_actions = local_actions
	else:
		var keys = local_actions.keys()
		for k in keys:
			if tmp_actions.has(k):continue
			tmp_actions[k] = local_actions[k]
			
# 添加动作映射
func add_action(action,action_infos,use_def=false):
	var event_setting:Array
	if action_infos.latest_setting && !use_def:
		event_setting = action_infos.latest_setting
	else:
		event_setting = action_infos.default_setting
		
	if event_setting.size() < 7:return 
	
	var et = null
	match int(event_setting[1]):
		0:
			et = InputEventKey.new()
			et.scancode = int(event_setting[2])
			et.physical_scancode = int(event_setting[3])
			et.shift = event_setting[4]
			et.alt = event_setting[5]
			et.control = event_setting[6]
		1: 
			et = InputEventMouseButton.new()
			et.button_index = int(event_setting[2])
		_:
			return 
	
	if InputMap.has_action(action):
		InputMap.action_erase_events(action)
	else:
		InputMap.add_action(action)
	InputMap.action_add_event(action,et)
	return et

# 重置键位设置
func reset_all_actions():
	for x in action_link_bt:
		var bt = action_link_bt[x]
		var et = add_action(x,tmp_actions[x],true)
		if et != null:
			bt.find_node("LabelAction2").text = trans_event_to_name(et)
		else:
			bt.find_node("LabelAction2").text = ""
	tmp_actions = {}
	save_input_setting()

# 检查按钮可用性
func check_action_able(action_info):
	var show_mode = action_info.get("show_mode")
	if show_mode == null:
		return false
	elif int(show_mode) == 0:
		return true
	elif int(show_mode) == 1 && !sys.isTest:
		return true
	elif int(show_mode) == 2 && sys.isTest:
		return true
	else:
		return false
